package vip.lsjscl.flowboot.workflow.service;

import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.lsjscl.flowboot.util.constants.TaskStatus;
import vip.lsjscl.flowboot.workflow.entity.DKActivity;
import vip.lsjscl.flowboot.workflow.entity.DKRuntimeTask;
import vip.lsjscl.flowboot.workflow.repository.DKActivityRepository;
import vip.lsjscl.flowboot.workflow.repository.DKRuntimeTaskRepository;
import vip.lsjscl.flowboot.workflow.repository.DKTransitionRepository;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务服务
 *
 * @author zhangxingju
 * @date 2025/02/14
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class DKRuntimeTaskService {

    private final DKRuntimeTaskRepository runtimeTaskRepository;

    private final DKActivityRepository activityRepository;

    private final DKTransitionRepository transitionRepository;

    /**
     * 创建初始运行时任务
     */
    public void createInitialRuntimeTask(List<DKActivity> nextActivityList) {
        for (DKActivity nextActivity : nextActivityList) {
            DKRuntimeTask nextRuntimeTask = new DKRuntimeTask();
            nextRuntimeTask.setActivity(nextActivity);
            nextRuntimeTask.setBusinessId(nextActivity.getBusinessId());
            nextRuntimeTask.setStatus(TaskStatus.PENDING);
            nextRuntimeTask.setWorkflowVersionId(nextActivity.getWorkflowVersionId());
            runtimeTaskRepository.save(nextRuntimeTask);
        }
    }

    public DKActivity findStartActivity(List<DKActivity> activities) {
        // 找到没有入边的节点作为开始节点
        return activities.stream()
                .filter(activity -> !hasIncomingTransitions(activity))
                .findFirst()
                .orElse(null);
    }

    public List<DKActivity> findEndActivities(List<DKActivity> activities) {
        // 找到所有没有出边的节点作为结束节点
        return activities.stream()
                .filter(activity -> !hasOutgoingTransitions(activity))
                .collect(Collectors.toList());
    }

    public boolean hasIncomingTransitions(DKActivity activity) {
        return !transitionRepository.findAllByToActivity(activity).isEmpty();
    }

    public boolean hasOutgoingTransitions(DKActivity activity) {
        return !transitionRepository.findAllByFromActivity(activity).isEmpty();
    }

    /**
     * 查询待办任务
     */
    public List<DKRuntimeTask> getTodoTasks(String userId, String deptId) {
        if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(deptId)) {
            return runtimeTaskRepository.findByUserIdOrDeptIdAndStatus(userId, deptId, TaskStatus.PENDING.getCode());
        }
        else if (StringUtils.isNotBlank(userId)) {
            return runtimeTaskRepository.findByUserIdAndStatus(userId, TaskStatus.PENDING.getCode());
        }
        else if (StringUtils.isNotBlank(deptId)) {
            return runtimeTaskRepository.findByDeptIdAndStatus(deptId, TaskStatus.PENDING.getCode());
        }
        return Collections.emptyList();
    }

    /**
     * 获取运行时已完成的任务
     */
    public List<DKRuntimeTask> getCompletedRuntimeTasks(String userId, String deptId) {
        if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(deptId)) {
            return runtimeTaskRepository.findByUserIdOrDeptIdAndStatus(userId, deptId, TaskStatus.COMPLETED.getCode());
        }
        else if (StringUtils.isNotBlank(userId)) {
            return runtimeTaskRepository.findByUserIdAndStatus(userId, TaskStatus.COMPLETED.getCode());
        }
        else if (StringUtils.isNotBlank(deptId)) {
            return runtimeTaskRepository.findByDeptIdAndStatus(deptId, TaskStatus.COMPLETED.getCode());
        }
        return Collections.emptyList();
    }

    /**
     * 查询所有任务（包括待办和已办）
     */
    public Map<String, Object> getAllTasks(String userId, String deptId) {
        Map<String, Object> result = new HashMap<>();
        result.put("todoTasks", getTodoTasks(userId, deptId));
        return result;
    }

    /**
     * 获取待办理任务
     *
     * @param userId 用户 ID
     * @return {@link List }<{@link DKRuntimeTask }>
     */
    public List<DKRuntimeTask> getTodoTasksByActivityCode(String userId, String code) {
        return runtimeTaskRepository.findByUserIdAndStatusAndActivityCode(userId, code, TaskStatus.PENDING.getCode());
    }
}